package br.unicamp.ic.sgct.server.dominio.servicos;

import it.biobytes.ammentos.Ammentos;
import it.biobytes.ammentos.PersistenceException;
import it.biobytes.ammentos.query.SqlQueryFilter;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import br.unicamp.ic.sgct.client.aplicacao.ucs.cancelamento.CancelamentoService;
import br.unicamp.ic.sgct.client.dominio.exception.InfraException;
import br.unicamp.ic.sgct.client.dominio.to.InscricaoTO;
import br.unicamp.ic.sgct.client.dominio.to.SalaTO;
import br.unicamp.ic.sgct.client.dominio.to.SessaoTO;
import br.unicamp.ic.sgct.client.dominio.to.UsuarioTO;
import br.unicamp.ic.sgct.server.dominio.entidades.Inscricao;
import br.unicamp.ic.sgct.server.dominio.entidades.Sessao;
import br.unicamp.ic.sgct.server.dominio.entidades.Usuario;
import br.unicamp.ic.sgct.server.recursos.persistencia.AmmentosConnection;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class CancelamentoServiceImpl extends RemoteServiceServlet implements
		CancelamentoService {

	private boolean aceitarCancelamento(Date dataAtual, Date dataEfetivacaoPagamento) {
		
		System.out.println(dataEfetivacaoPagamento);
		System.out.println(dataAtual);

		int MSEGUNDOS_DIA = 24 * 60 * 60 * 1000;
		int diferenca = (int)((dataAtual.getTime() - 
				dataEfetivacaoPagamento.getTime()) / MSEGUNDOS_DIA); 

		if (diferenca > 7) {
 			return false;
		}
		else {
			return true;
		}
	}

	public void cancelar(UsuarioTO usuario) throws InfraException {
		List<Usuario> lstUsuario;
		System.out
				.println("\nCancelamentoServiceImpl :: cancelar(Usuario) acionado");

		try {
			Usuario usuarioPersist = new Usuario(usuario);
			
			AmmentosConnection.instance();

			lstUsuario = Ammentos.load(Usuario.class,
					new SqlQueryFilter("email like '" + usuarioPersist.getEmail() + 
							"' and senha like '" + usuarioPersist.getSenha() + "'"));

			if (lstUsuario != null && lstUsuario.isEmpty()) {
				throw new InfraException("Usu\u00e1rio n\u00e3o se encontra " +
						"inscrito para o evento!"); 
			}
			if (lstUsuario != null && !lstUsuario.isEmpty()) {
				// Verifica se h� mais de um usu�rio registrado com o mesmo
				// email e senha
				if (lstUsuario.size() > 1) {
					throw new InfraException("H\u00e1 mais de um " +
							"usu\u00e1rio registrado com seu email e senha. Favor " +
							"procure o administrador do sistema!");
				}
				
				//INICIO - EXERC. 5
				StringBuffer sb = new StringBuffer();
				int i = 0;
				for(InscricaoTO inscricao : usuario.getInscricaoList()){
				
					sb.append(inscricao.getId());
					i++;
					if(i < usuario.getInscricaoList().size()){
						sb.append(",");
					}
				}
				// Verifica se j� se passaram 7 dias da inscricao no evento
				List<Inscricao> lstInscricao = Ammentos.load(Inscricao.class,
						new SqlQueryFilter("id_inscricao in ("+sb.toString()+")"));
				
				Date dataAtual = new Date(System.currentTimeMillis());
				for(Inscricao inscricaoPersist : lstInscricao){
					Date dataPgto = inscricaoPersist.getDataEfetivacaoPagto();
					if (aceitarCancelamento(dataAtual, dataPgto)) {
						// Processa o cancelamento de inscricao
						inscricaoPersist.setSituacao(3);
						
						Ammentos.openTransaction();
				
						Ammentos.save ( lstUsuario.get(0) );
						Ammentos.save ( lstUsuario.get(0).getPessoa() );
						Ammentos.save(inscricaoPersist);
						Ammentos.commitTransaction();
					
					}
					else {
						throw new InfraException("Per\u00a1odo de " +
						"cancelamento de sua inscri\u00e7\u00e3o ultrapassado!");
					}
				}
				//FIM - EXERC. 5
				
			}

		}
		catch (PersistenceException e) {
			throw new InfraException("InfraException: " + e.getMessage());
		}
	}

	//INICIO - EXERC. 5
	public List<InscricaoTO> listarInscricoes(UsuarioTO usuario) throws InfraException {
		
		List<Usuario> lstUsuario;
		List<Inscricao> lstInscricao = new ArrayList<Inscricao>();
		Usuario usuarioPersist = new Usuario(usuario);
		
		List<InscricaoTO> lstInscricaoTO = new ArrayList<InscricaoTO>();

			try {
				AmmentosConnection.instance();	
				
				lstUsuario = Ammentos.load(Usuario.class,
						new SqlQueryFilter("email like '" + usuarioPersist.getEmail() + 
								"' and senha like '" + usuarioPersist.getSenha() + "'"));
				if(lstUsuario==null || lstUsuario.isEmpty()){
					throw new InfraException("Usu\u00e1rio n\u00e3o se encontra " +
					"inscrito para o evento!"); 
				}
				lstInscricao = Ammentos.load(Inscricao.class,
						new SqlQueryFilter("id_usuario = " + lstUsuario.get(0).getId() + 
								" and situacao = 0 or situacao = 1 "));
				
				for(Inscricao inscricao : lstInscricao){
					InscricaoTO inscricaoTO = new InscricaoTO();
					inscricaoTO.setId(inscricao.getId());
					inscricaoTO.setDataEfetivacaoPagto(inscricao.getDataEfetivacaoPagto());
					inscricaoTO.setDataInscricao(inscricao.getDataInscricao());
					inscricaoTO.setSituacao(inscricao.getSituacao());
					
					usuario.setId(usuarioPersist.getId());
					usuario.setEmail(usuarioPersist.getEmail());
					usuario.setSenha(usuarioPersist.getSenha());
					inscricaoTO.setUsuario(usuario);
					Sessao sessao = inscricao.getSessao();
					
					SessaoTO sessaoTo = new SessaoTO();
				    
				    sessaoTo.setId(sessao.getId());
				    sessaoTo.setApresentacoes( null );
				    sessaoTo.setData(sessao.getData());
				    sessaoTo.setPeriodo(sessao.getPeriodo());
				    sessaoTo.setSequencialPeriodo(sessao.getSequencialPeriodo());
				    sessaoTo.setTema(sessao.getTema());
				    
				    SalaTO salaTo = new SalaTO();
				    
				    salaTo.setId(sessao.getSala().getId());
				    salaTo.setCapacidade(sessao.getSala().getCapacidade());
				    salaTo.setIdentificacao(sessao.getSala().getIdentificacao());
				    
				    sessaoTo.setSala(salaTo);
					inscricaoTO.setSessao(sessaoTo);
					lstInscricaoTO.add(inscricaoTO);
				}
			} catch (PersistenceException e) {
				// TODO Auto-generated catch block
				throw new InfraException("InfraException: " + e.getMessage());
			}
	
		
			
			
		return lstInscricaoTO;
	}
	//FIM - EXERC. 5
}